﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.CompilerServices;

using Common;


namespace Server
{
    public class ServerSocket
    {
        private List<ServerListener> clientListeners;

        public ServerSocket()
        {
           clientListeners = new List<ServerListener>();
           RunServer();
        }

        private void RunServer()
        {
            try
            {
                IPAddress ipAd = IPAddress.Parse("127.0.0.1");
                TcpListener myList = new TcpListener(ipAd, 8001);
                myList.Start();


                Console.WriteLine("The server is running at port 8001...");
                Console.WriteLine("The local End point is  :" + myList.LocalEndpoint);
                Console.WriteLine("Waiting for a connection.....");

                while (true)
                {
                    TcpClient tpC = myList.AcceptTcpClient();
                    clientListeners.Add(new ServerListener(tpC, this.processObject, this));
                    PrintAllClients();
                }
                myList.Stop();

            }
            catch (Exception e)
            {
                Console.WriteLine("Error..... " + e.StackTrace);
            }
        }

        

        public void PrintAllClients()
        {
            Console.WriteLine("Current clients:");
            foreach (var client in clientListeners)
            {
                Console.WriteLine(client.ToString());
            }
            Console.WriteLine();
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public void processObject(Object o)
        {
            Console.WriteLine(o.ToString());
            foreach (var client in clientListeners)
            {
                client.SendObject(o);
            }
        }
         
        [MethodImpl(MethodImplOptions.Synchronized)]
        public void DeleteFromClientListeners(ServerListener serverListener)
        {
            clientListeners.Remove(serverListener);
            PrintAllClients();
        }

        public static void Main()
        {
            ServerSocket p = new ServerSocket();
        }
    }
}
